﻿using System;
using System.Collections.ObjectModel;
using GalaSoft.MvvmLight.Command;
using ZOIL.DataModel;
using System.Windows.Data;
using System.Linq;
using System.Windows.Markup;

namespace ZOIL.DataBackend.Server
{
    /// <summary>
    /// The ViewModel for the Server Class. Provides Properties and Methods for the View to consume.
    /// </summary>
    public class ServerViewModel : BaseViewModel
    {
        #region Commands

        public RelayCommand AddDatabaseCommand { get; private set; }
        public RelayCommand DeleteDatabaseCommand { get; private set; }

        #endregion

        private CollectionViewSource _cvsDatabases;
        public CollectionViewSource CVSDatabases
        {
            get
            {
                return _cvsDatabases;
            }
            private set
            {
                _cvsDatabases = value;
                RaisePropertyChanged("CVSDatabases");
            }
        }

        public CollectionView CVSDatabasesView
        {
            get
            {
                return (CollectionView)CVSDatabases.View;
            }
        }

        public ServerViewModel()
        {
            PropertyChanged += ServerViewModel_PropertyChanged;

            AddDatabaseCommand = new RelayCommand(OnAddDatabase);
            DeleteDatabaseCommand = new RelayCommand(OnDeleteDatabase);
        }

        void ServerViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if(e.PropertyName == "Model")
            {
                Databases = new ObservableCollection<DatabaseConfigurationViewModel>();
                ViewModelCollectionSynchronizer<DatabaseConfigurationViewModel, DatabaseConfiguration> synchronizer = new ViewModelCollectionSynchronizer<DatabaseConfigurationViewModel, DatabaseConfiguration>(_databases, (Model as Server).Databases, new DatabaseConfigurationToDatabaseConfigurationViewModelConverter(), true);
                CVSDatabases = new CollectionViewSource();
                CVSDatabases.Source = Databases;
                CVSDatabases.SortDescriptions.Add(new System.ComponentModel.SortDescription("Name", System.ComponentModel.ListSortDirection.Ascending));
            }
        }

        #region commands

        #region add database command
        
        void OnAddDatabase()
        {
            DatabaseConfiguration config = new DatabaseConfiguration();
            config.Name = "NewDatabase-" + (Model as Server).Databases.Count;
            config.Port = 4488;
            config.Users.Add(new DatabaseUser("ztv", "ztv"));
            config.UseMemoryIOAdapter = true;
            (Model as Server).Databases.Add(config);
            CVSDatabasesView.MoveCurrentTo(_databases.Where(vm => vm.Model == config).Single());
        }
        
        #endregion

        #region delete database command
        
        void OnDeleteDatabase()
        {
            Object o = CVSDatabases.View.CurrentItem;
            DatabaseConfigurationViewModel configVM = o as DatabaseConfigurationViewModel; 
            (Model as Server).Databases.Remove(configVM.Model as DatabaseConfiguration);
        }
        
        #endregion

        #endregion

        /// <summary>
        /// Holds the databases that are configured with the GUI
        /// </summary>
        private ObservableCollection<DatabaseConfigurationViewModel> _databases;
        public ObservableCollection<DatabaseConfigurationViewModel> Databases
        {
            get
            {
                return _databases;
            }
            private set
            {
                _databases = value;
                RaisePropertyChanged("Databases");
            }
        }
    }

    public class DummyConverter : IValueConverter
    {

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return value;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class StatusToBooleanConverter : MarkupExtension, IValueConverter
    {
        private static StatusToBooleanConverter _converter;
        public override object ProvideValue(IServiceProvider serviceProvider)
        {
            if (_converter == null)
            {
                _converter = new StatusToBooleanConverter();
            }
            return _converter;
        }

        #region IValueConverter Members

        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            DatabaseStatus status = (DatabaseStatus)value;

            switch (status)
            {
                case DatabaseStatus.Running:
                    return false;
                case DatabaseStatus.Stopped:
                    return true;
                default:
                    return true;
            }
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

    public class DatabaseConfigurationToDatabaseConfigurationViewModelConverter : IViewModelConverter<DatabaseConfigurationViewModel, DatabaseConfiguration>
    {

        #region IViewModelConverter<DatabaseConfigurationViewModel,DatabaseConfiguration> Members

        public DatabaseConfigurationViewModel getViewModel(DatabaseConfiguration model)
        {
            DatabaseConfigurationViewModel vm = new DatabaseConfigurationViewModel();
            vm.Model = model;
            return vm;
        }

        public DatabaseConfiguration getModel(DatabaseConfigurationViewModel viewModel)
        {
            return viewModel.Model as DatabaseConfiguration;
        }

        #endregion
    }
}
